<?php

namespace app\admin\dao;

use app\common\model\Consulting;
use app\common\model\ConsultingQuestion;
use app\common\model\Trade;
use ShidianUtil\Thinkphp\Dao\DaoTrait;

/**
 * ConsultingDao 数据访问对象
 * Class ConsultingDao
 * @package app\admin\dao
 * @method Consulting findByPK(?int $id, $field = true)
 * @method \think\Collection selectAll(?int $page, ?int $page_size, $field = true)
 * @method Consulting insertActive(array $params, array $allow_field = [])
 * @method Consulting updateActive(Consulting $model, array $params, array $allow_field = [])
 * @method Consulting findAndUpdateActive(int $id, array $params, array $allow_field = [])
 * @method Consulting updateActiveByClosure(\Closure $closure, array $params, array $allow_field = [])
 * @method void deleteModel(Consulting $model)
 * @method void deleteById(int|array|\Closure $id, bool $force = false)
 * @link https://www.kancloud.cn/manual/thinkphp6_0/1037579
 * @link https://www.kancloud.cn/manual/think-orm/1257998
 * @link https://www.kancloud.cn/thinkphp/master-database-and-model/265551
 */
class ConsultingDao
{
    use DaoTrait;

    /**
     * @var Consulting
     */
    private $baseModel;

    /**
     * ConsultingDao constructor.
     */
    public function __construct()
    {
        $this->baseModel = Consulting::class;
    }

    /**
     * 咨询列表
     * @param $consultingStatus
     * @param $consultingServerId
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param int|null $page
     * @param int|null $page_size
     * @return array
     */
    public function listConsulting($consultingStatus, $consultingServerId, $provinceId, $cityId, $startTime, $endTime, $kw, ?int $page, ?int $page_size): array
    {

        $tableName = Consulting::getTable();

        $query = Consulting::when(is_id($consultingServerId), fn($query) => $query->where("$tableName.consultingServerId", $consultingServerId))
            ->when(is_id($provinceId), fn($query) => $query->where("$tableName.provinceId", $provinceId))
            ->when(is_id($cityId), fn($query) => $query->where("$tableName.cityId", $cityId))
            ->when(is_numeric($startTime), fn($query) => $query->where("$tableName.created", '>=', $startTime))
            ->when(is_numeric($endTime), fn($query) => $query->where("$tableName.created", '<=', $endTime))
            ->when(not_blank($kw), fn($query) => $query->leftJoin('member m', "$tableName.memberId=m.id")
                ->leftJoin('member l', "$tableName.lawyerId=l.id")
                ->search('no|ask|m.nickname|m.phone|l.realname|l.phone', $kw))
            ->where("$tableName.status", '>=', 1);

        if ($consultingStatus == 1) {
            //未开始

            $query->where('lawyerId', '0');
        } elseif ($consultingStatus == 2) {
            // 进行中

            $query->where('isEnd', 0);
        } elseif ($consultingStatus == 3) {
            // 已完成

            $query->where('isEnd', 1);
        } else {
            // 全部

            // $query->where('lawyerId', '<>', '0');
        }

        $query->tableField(true, $tableName)
            ->with([
                'province' => fn($query) => $query->shortArea(),
                'city' => fn($query) => $query->shortArea(),
                'consultingServer' => fn($query) => $query->field(['id', 'serverType', 'price', 'name']),
                'member' => fn($query) => $query->shortMember(),
                'lawyer' => fn($query) => $query->shortLawyer()
                    ->with([
                        'memberInfo' => fn($subQuery) => $subQuery->field([
                            'memberId',
                            'practiceNumber',
                            'cityId',
                        ])->with([
                            'city' => fn($query) => $query->shortArea(),
                        ])->hidden(['memberId'])
                    ])
            ])->withCount([
                'refundingTrades' => fn($query) => $query->where('payStatus', Trade::PAID)->where('refundStatus', Trade::REFUNDING),
            ])->withSum([
                'trades' => fn($query) => $query->where('payStatus', Trade::PAID)->whereIn('refundStatus', [Trade::NOTREFUND, Trade::REFUNDING, Trade::REFUND_FAILED]),
            ], 'payMoney')
            ->withAttr([
                'consultingStatus' => function ($value, $data) {
                    $isEnd = $data['isEnd'] ?? null;
                    $lawyerId = $data['lawyerId'] ?? null;
                    if (is_id($lawyerId) && $isEnd == 1) {
                        return '3';
                    } elseif (is_id($lawyerId) && $isEnd == 0) {
                        return '2';
                    }
                    return '1';
                },
                'trades_sum' => fn($value) => $value ?: 0])
            ->append(['consultingStatus'])
            ->order("$tableName.questionId", 'DESC')
            ->order("$tableName.isAsked", 'DESC')
            ->order("$tableName.id", 'DESC')
            ->paging($page, $page_size);

        return listOutput($query, $page_size);
    }

    /**
     * 咨询列表
     * @param $categoryId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param int|null $page
     * @param int|null $page_size
     * @return array
     */
    public function listQuestionConsulting($categoryId, $startTime, $endTime, $kw, ?int $page, ?int $page_size): array
    {

        $tableName = ConsultingQuestion::getTable();

        $query = ConsultingQuestion::when(is_id($categoryId), fn($query) => $query->where("$tableName.categoryId", $categoryId))
            ->when(is_numeric($startTime), fn($query) => $query->where("$tableName.created", '>=', $startTime))
            ->when(is_numeric($endTime), fn($query) => $query->where("$tableName.created", '<=', $endTime))
            ->when(not_blank($kw), fn($query) => $query->leftJoin('consulting c', "$tableName.id=c.questionId")
                ->leftJoin('member m', "$tableName.memberId=m.id")
                ->leftJoin('member l', "$tableName.lawyerId=l.id")
                ->search("c.no|$tableName.ask|m.nickname|m.phone|l.realname|l.phone", $kw))
            ->with([
                'member' => fn($query) => $query->shortMember(),
                'lawyer' => fn($query) => $query->shortMember(),
                'category' => fn($query) => $query->field(['id', 'name']),
                'consultingArr' => function ($query) {

                    $tableName = Consulting::getTable();

                    $query->where("$tableName.status", '>=', 1)
                        ->tableField(true, $tableName)
                        ->with([
                            'province' => fn($query) => $query->shortArea(),
                            'city' => fn($query) => $query->shortArea(),
                            'consultingServer' => fn($query) => $query->field(['id', 'serverType', 'price', 'name']),
                            'member' => fn($query) => $query->shortMember(),
                            'lawyer' => fn($query) => $query->shortLawyer()
                                ->with([
                                    'memberInfo' => fn($subQuery) => $subQuery->field([
                                        'memberId',
                                        'practiceNumber',
                                        'cityId',
                                    ])->with([
                                        'city' => fn($query) => $query->shortArea(),
                                    ])->hidden(['memberId'])
                                ])
                        ])
                        ->withCount([
                            'refundingTrades' => fn($query) => $query->where('payStatus', Trade::PAID)->where('refundStatus', Trade::REFUNDING),
                        ])
                        ->withSum([
                            'trades' => fn($query) => $query->where('payStatus', Trade::PAID)->whereIn('refundStatus', [Trade::NOTREFUND, Trade::REFUNDING, Trade::REFUND_FAILED]),
                        ], 'payMoney')
                        ->withAttr([
                            'consultingStatus' => function ($value, $data) {
                                $isEnd = $data['isEnd'] ?? null;
                                $lawyerId = $data['lawyerId'] ?? null;
                                if (is_id($lawyerId) && $isEnd == 1) {
                                    return '3';
                                } elseif (is_id($lawyerId) && $isEnd == 0) {
                                    return '2';
                                }
                                return '1';
                            },
                            'trades_sum' => fn($value) => $value ?: 0])
                        ->append(['consultingStatus'])
                        ->orderField('lawyerId', ['0'], 'ASC');
                    // ->order("$tableName.isAsked", 'DESC')
                    // ->order("$tableName.id", 'DESC');
                }
            ])
            ->group("$tableName.id")
            ->order("$tableName.ord", 'ASC')
            ->order("$tableName.id", 'DESC')
            ->paging($page, $page_size);

        return listOutput($query, $page_size);
    }

}
